The purpose of this notebook is to visualize the Ontario Railway Network. All data is taken from Ontario GeoHub.
import os
import geopandas as gpd
cwd = os.getcwd()
tracks = gpd.read_file(cwd + "/Data/ORWNTRK/LIO-2022-10-19/ORWN_Track.shp")
marker_posts = gpd.read_file(cwd + "/Data/ORWNMKPO/LIO-2022-10-19/ORWN_MARKER_POST.shp")
The map shows each subdivision in a different colour. Hovering over the subdivisions will show their name and operator.
CN, CP, and Metrolinx are shown by default, and subdivisions owned by other operators can be viewed by selecting them from the layer control at the top right of the map.
The map style can also be changed from the layer control. For the satellite view, turning on the Road Labels overlay will show the names of all the roads. This can be turned off when using another map style. An overlay for OpenRailwayMap is also available for reference.
import folium
import distinctipy
import random
# Define map and style choices
# See http://leaflet-extras.github.io/leaflet-providers/preview/ for options
m = folium.Map(location=[43.67621,-79.40530], zoom_start=6, tiles=None)
folium.TileLayer(tiles = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
attr = 'Esri', name = 'Esri Satellite', show=True).add_to(m)
folium.TileLayer(tiles='openstreetmap', name='Open Street Map').add_to(m)
folium.TileLayer(tiles='CartoDB dark_matter', name='CartoDB Dark Matter').add_to(m)
folium.TileLayer(tiles='CartoDB positron', name='CartoDB Positron').add_to(m)
folium.TileLayer(tiles='https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png',
attr='Open Railway Map', name='Open Railway Map', overlay=True, show=False).add_to(m)
folium.TileLayer(tiles='https://stamen-tiles-{s}.a.ssl.fastly.net/toner-hybrid/{z}/{x}/{y}.png',
attr='Stamen Design', name='Road Labels', overlay=True, show=True).add_to(m)
# Tracks Data
# Generate a list of unique colours (as hex codes) to use for colouring all the subdivisions
# Fix the random seed so results don't change between runs
random.seed(15)
subs = tracks['SUBDI1NAME'].unique()
subs_dict = {k: v for v, k in enumerate(subs)}
sub_colors = distinctipy.get_colors(len(tracks['SUBDI1NAME'].unique()))
sub_colors = ['#%02x%02x%02x' % (int(255*c[0]), int(255*c[1]), int(255*c[2])) for c in sub_colors]
# Create a feature group for each operator
# Hide all the operators by default except for those in default_layers
default_layers = ['Canadian National', 'GO Transit – Metrolinx', 'Canadian Pacific']
features = {}
for row in tracks['OPERATOENA'].unique():
features[row] = folium.FeatureGroup(name=row, show=True if row in default_layers else False)
for index, row in tracks.iterrows():
# Define GeoJson for track segment
geo_j = gpd.GeoSeries(row['geometry']).to_json()
color = sub_colors[subs_dict[row['SUBDI1NAME']]]
geo_j = folium.GeoJson(data=geo_j, name=row['SUBDI1NAME'], style_function=lambda x, color=color : {'color':color})
label = "Subdivision: " + row['SUBDI1NAME'] + \
"<br>" + "Operator: " + row['OPERATOENA'] + \
"<br>" + "Track Class: " + str(row['TRACKCLASS'])
folium.Tooltip(label).add_to(geo_j)
# Add track segment to the feature group for its operator
geo_j.add_to(features[row['OPERATOENA']])
# Add feature groups to the map
for row in tracks['OPERATOENA'].unique():
features[row].add_to(m)
# Marker Posts Data
# To-do: add to map
# Add layer Control to the map
folium.LayerControl().add_to(m)
# Show the map
m